

package control;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar; 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Timer;
import model.Account;
import model.Share;
import model.Time;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
  
/**
 * PriceChartController.java
 * @author Diego Schmaedech
 * @version 1.0
 * @since Release Beta
 * @link  http://code.google.com/p/economylabs
 * Created on August 2, 2008, 2:34 AM
 */
public class PriceChartController extends ApplicationFrame implements ActionListener {

    private Account account;
    private Share share;
    private Time time;    
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");      
    private XYSeries series1;
    private double incrementSerie1;
    private XYSeries series2;
    private double incrementSerie2;
    private XYSeries series3;
    private double incrementSerie3;
    private XYSeries series4;
    private double incrementSerie4;
    private XYSeries series5;
    private double incrementSerie5;
    private XYSeries series6; 
    private double incrementSerie6;         
    private String timestamp; 
    private int interval;
    private Timer timer;
    private int chronometer;     
    private Timer timerForward;
    private int timerController=0; 
    private int countForward=0;
    private boolean simPaused = false;    
    final JButton jbPlay = new JButton("<html><b>Come&ccedil;ar</b></html>");
    final JButton jbStop = new JButton("<html><b>Parar</b></html>");
    final JButton jbForward = new JButton("<html><b>Avan&ccedil;ar Periodo</b></html>");
    final JProgressBar jpbTimerPeriod = new JProgressBar(0,4);
          
    public PriceChartController(Account controlledAccount, Share controlledShare, Time controlledTime) {

        super("EconomyLabs");
        setAccount(controlledAccount);
        setShare(controlledShare);
        setTime(controlledTime);
        setInterval(getTime().getInterval());
        this.countForward=0; 
         
        final XYSeriesCollection dataset = new XYSeriesCollection();
         
        setSeries1( new XYSeries(getShare().getShareName(0)));
        setSeries2( new XYSeries(getShare().getShareName(1)));
        setSeries3( new XYSeries(getShare().getShareName(2)));
        setSeries4( new XYSeries(getShare().getShareName(3)));
        setSeries5( new XYSeries(getShare().getShareName(4)));
        setSeries6( new XYSeries(getShare().getShareName(5)));
        dataset.addSeries(getSeries1());
        dataset.addSeries(getSeries2());
        dataset.addSeries(getSeries3());
        dataset.addSeries(getSeries4());
        dataset.addSeries(getSeries5());
        dataset.addSeries(getSeries6());
        
        final JFreeChart chart = createChart(dataset);
        final ChartPanel chartPanel = new ChartPanel(chart);
        jbForward.setActionCommand("FORWARD");
        jbForward.setIcon( new ImageIcon("images/media/StepForward24.gif")); 
        jbForward.setBackground(Color.WHITE);
        jbForward.addActionListener(this);
        jbForward.setEnabled(false); 
        String strjocker =   "<font color=\"#000000\">" + "<b>" + 
                               "Time is money....." + "</b>"
                         + "</font>"  ;
           
        jbForward.setToolTipText("<html>Acione para <b>avançar </b>o periodo da simulação."+strjocker+"</html>");
 
        jbPlay.setActionCommand("PLAY");        
        jbPlay.setIcon( new ImageIcon("images/media/Play24.gif"));
        jbPlay.setBackground(Color.WHITE);
        jbPlay.addActionListener(this);
        jbPlay.setToolTipText("<html>Acione para <b>começar </b> a simulação.</html>");
      
        jbStop.setActionCommand("STOP");
        jbStop.setIcon( new ImageIcon("images/media/Pause24.gif")); 
        jbStop.setBackground(Color.WHITE);
        jbStop.addActionListener(this);
        jbStop.setEnabled(false); 
        jbStop.setToolTipText("<html>Acione para <b>dar um tempo </b>na simulação.</html>");
 
        //set swing panel
        JPanel gridBagPanel = new JPanel();
        GridBagConstraints gridBagConstraints;

        gridBagPanel.setLayout(new java.awt.GridBagLayout());        
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 438));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;      
        gridBagPanel.add(chartPanel, gridBagConstraints);
        
        //Jbuttonnnnsssss
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new java.awt.FlowLayout()); 
        jbPlay.setPreferredSize(new java.awt.Dimension(150, 40));     
        buttonPanel.add(jbPlay);        
        jbForward.setPreferredSize(new java.awt.Dimension(150, 40));           
        buttonPanel.add(jbForward);        
        jbStop.setPreferredSize(new java.awt.Dimension(150, 40));         
        buttonPanel.add(jbStop);          
        buttonPanel.setPreferredSize(new java.awt.Dimension(500, 50));
        buttonPanel.setBackground(Color.WHITE);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;      
        gridBagPanel.add(buttonPanel, gridBagConstraints);       
        setContentPane(gridBagPanel);
        getContentPane().setFocusCycleRoot(true);
    }
 
     public void play(){        
       
        if(simPaused==false){
 
            getTime().play(); 
            getAccount().play();
            getShare().play();
            startClock(); 
            updatePlotSeries();
            jbPlay.setEnabled(false);
            jbStop.setEnabled(true);
            jbForward.setEnabled(true);
            
            if(getTime().getPeriodsForward()!=0){
                timerController=getTime().getPeriodsForward();
                timerForward = new Timer(100, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                         timerController--;
                         forward();
                         if(timerController==0){
                             timerForward.stop();
                         }
                     }

                });
                timerForward.start(); 
            } 
        }else{
         
            getTime().play(); 
            getAccount().replay();
            getShare().play();
            timer.start(); 
            updatePlotSeries();
            jbPlay.setEnabled(false);
            jbStop.setEnabled(true);
            jbForward.setEnabled(true);
        }
        
    }
    
    public void stop(){ 
        jbPlay.setEnabled(true);
        jbPlay.setText("<html>Retornar</html>");
        jbPlay.setToolTipText("<html>Acione para <i>Retornar</i></html>");
        jbStop.setEnabled(false);
        jbForward.setEnabled(false);
            
        getTime().stop();
        getShare().stop();
        getAccount().stop();
        
        pauseClock();
        
        JOptionPane.showMessageDialog(rootPane, "Para continuar a simulação acione o botão <i>Retornar</i>");
        
    }
    
    public void forward(){
        this.countForward++;
        if(countForward==getTime().getMaxPeriod()){
            pauseClock();
             
            jbPlay.setEnabled(false);
            jbStop.setEnabled(false);
            jbForward.setEnabled(false); 
           
            getTime().stop();
            getShare().stop();
            getAccount().stop();
             //notas do jocker-----        
            String ans;
            ans = JOptionPane.showInputDialog(null, "<html>Acabaram os periodos para esta simulação.<br />" +
                    " Agradeçemos sua colaboração em nossos estudos.<br />" +
                    "Para salvar os dados da sua participação digite <i>sim</i> no campo abaixo e acione OK</html>","Mensagem!",JOptionPane.INFORMATION_MESSAGE);
            if(ans == null || ans.equals("")){
               System.exit(0);
            }
            if(ans.equals("sim")){
               getAccount().saveAs(); 
            }
          
        //fim do jocker------- 
            
        }else{
            
            getTime().forward(getTime().getPeriod(), getTime().getTimestamp());
            getShare().forward(getTime().getPeriod());
            getAccount().forward(getTime().getPeriod(), getShare().getShareTable());

            updatePlotSeries();
            restartClock();
            
        }  
    }
    
      
    private void restartClock(){            
        chronometer = 0;
        timer.start(); 
    }
     
    private void startClock(){
          
        timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                if (chronometer == getTime().getInterval()) { 
                    
                    forward();                      
                    restartClock(); 
                    
                }
                 
                chronometer++;
                getTime().setTimestamp(getStringClock());
                getTime().timerCounter(chronometer);
                 
                }
        });
        
        chronometer = 0;
        timer.start(); 
          
    }
   
    private void pauseClock(){
        //chronometer = 0;
        simPaused=true;
        getTime().timerCounter(chronometer);
        timer.stop(); 
        
    }
      
    private JFreeChart createChart(final XYDataset dataset) {
        JFreeChart result = ChartFactory.createXYLineChart(
            "Preço vs Periodo",
            "Periodo",
            "Preço",
            dataset,
            PlotOrientation.VERTICAL,
            true,
            false,
            false
        );
        
        
        final XYPlot plot = result.getXYPlot();
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
         
        renderer.setSeriesShapesVisible(1, true);        
        renderer.setSeriesStroke(0, new BasicStroke(2.0f));
        renderer.setSeriesStroke(1, new BasicStroke(2.0f));
        renderer.setSeriesStroke(2, new BasicStroke(2.0f));
        renderer.setSeriesStroke(3, new BasicStroke(2.0f));
        renderer.setSeriesStroke(4, new BasicStroke(2.0f));
        renderer.setSeriesStroke(5, new BasicStroke(2.0f));                 
        plot.setRenderer(renderer);         
        ValueAxis axis = plot.getDomainAxis();                  
        axis.setRange(1,getTime().getMaxPeriod());
        axis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 
        axis = plot.getRangeAxis(); 
        axis.setAutoRange(true);
        return result;
    }
    
    private void updatePlotSeries( ){                
        
        incrementSerie1 = getShare().getPurchasePrice(0); 
        incrementSerie2 = getShare().getPurchasePrice(1); 
        incrementSerie3 = getShare().getPurchasePrice(2); 
        incrementSerie4 = getShare().getPurchasePrice(3); 
        incrementSerie5 = getShare().getPurchasePrice(4); 
        incrementSerie6 = getShare().getPurchasePrice(5);
          
        getSeries1().add(getTime().getPeriod(), incrementSerie1 );
        getSeries2().add(getTime().getPeriod(), incrementSerie2 );
        getSeries3().add(getTime().getPeriod(), incrementSerie3  );
        getSeries4().add(getTime().getPeriod(), incrementSerie4 );
        getSeries5().add(getTime().getPeriod(), incrementSerie5 );
        getSeries6().add(getTime().getPeriod(), incrementSerie6 );
        
    }
    
    public void actionPerformed(final ActionEvent e) {
        if (e.getActionCommand().equals("FORWARD")) {
           forward();  
        }
        
        if (e.getActionCommand().equals("PLAY")) {
            play();
            
        }
        
        if (e.getActionCommand().equals("STOP")) {
            stop();
        }
    }
      
   
    //Metodos auxiliares, nao modifique
    private String getStringClock() {
          
        calendar.setTimeInMillis(System.currentTimeMillis());
        String strClock = dateFormat.format(calendar.getTime());
        return strClock;
    }
    
    public void setTime(Time time) {
        this.time = time;
    }
  
    public void setAccount(Account account) {
        this.account = account;
    }

    public void setShare(Share share) {
        this.share = share;
    }
 
    public Share getShare() {
        return share;
    }

    public Account getAccount() {
        return account;
    }

    public Time getTime() {
        return time;
    }

    public XYSeries getSeries1() {
        return series1;
    }

    public void setSeries1(XYSeries series1) {
        this.series1 = series1;
    }

    public XYSeries getSeries2() {
        return series2;
    }

    public void setSeries2(XYSeries series2) {
        this.series2 = series2;
    }

    public XYSeries getSeries3() {
        return series3;
    }

    public void setSeries3(XYSeries series3) {
        this.series3 = series3;
    }

    public XYSeries getSeries4() {
        return series4;
    }

    public void setSeries4(XYSeries series4) {
        this.series4 = series4;
    }

    public XYSeries getSeries5() {
        return series5;
    }

    public void setSeries5(XYSeries series5) {
        this.series5 = series5;
    }

    public XYSeries getSeries6() {
        return series6;
    }

    public void setSeries6(XYSeries series6) {
        this.series6 = series6;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    
    public int getInterval() {
        return interval;
    }

    public void setInterval(int interval) {
        this.interval = interval;
    }
}